#include "Qt3DPicker.h"

#include "Copy2DHandler.h"
#include "CmdManager.h"
#include "Scene.h"
#include "SendPointHandlerBase.h"
#include "SelectHandler3D.h"
#include "OSGNodeMask.h"
#include "Operation/OpAdd.h"
#include "QtOSGWidget.h"

Copy2DHandler::Copy2DHandler()
{
}

Copy2DHandler::~Copy2DHandler()
{
}

void Copy2DHandler::input(const QVariant& data, const QString& rawInput, CommandSource cs)
{
	auto scene = getScene();
	auto sph = getSendPointHandler();
	auto selector = qobject_cast<SelectHandler3D*>(getSelectHandler());
	if (data.type() == QVariant::Bool)
	{
		bool esc = !data.toBool();
		if (esc)
		{
			removeTempObjects();
			selector->clearSelection();
			clearInput();
			emit finished();
			return;
		}
	}

	auto widget3D = getWidget();
	if (status() == 0)
	{
		if (selector)
		{
			selector->clearSelection();
			selector->beginSelect(D2CurveMask);
			prompt(1, tr("选择对象: "));
		}
		else
		{
			emit finished();
		}
		return;
	}

	if (status() == 1)
	{
		if (selector && selector->done())
		{
			auto selections = selector->selectionSet();
			if (selections.size() > 0)
			{
				auto selection = *selections.begin();
				std::shared_ptr<Ent> ent = std::dynamic_pointer_cast<Ent>(selection);
				auto parent = ent->getParent();
				UCS* ucs = dynamic_cast<UCS*>(parent);
				if (ucs)
				{
					m_ucs = ucs;
				}
				else
				{
					remark(tr("请选择二维图形"));
					emit finished();
					return;
				}

				std::vector<std::shared_ptr<Ent>> clones;
				for (auto selection : selections)
				{
					std::shared_ptr<Ent> ent = std::dynamic_pointer_cast<Ent>(selection);
					auto parent = ent->getParent();
					UCS* ucs = dynamic_cast<UCS*>(parent);
					if (ucs != m_ucs)
						continue;
					auto clone = ent->clone();
					m_origins.push_back(ent);
					clones.push_back(clone);
					widget3D->pauseRenderThread();
					m_ucs->addChild(clone);
					widget3D->resumeRenderThread();
				}
				m_cloneVec.push_back(clones);
				if (sph)
				{
					sph->setPointMask(CS_LBTNDOWN | CS_MOUSEMOVE);
				}
				enableMouseHandler(MouseHandlerID::PointSender);
				cmdManager()->setPlane((Plane2DKind)m_ucs->getKind());
				prompt(2, tr("指定第一个点: "));
			}
			else
			{
				emit finished();
			}
		}
		return;
	}

	if(status() == 2)
	{
		osg::Vec3d ucspt;
		if (getPoint2D(*m_ucs, data, rawInput, cs, ucspt))
		{
			if (cs == CS_MOUSEMOVE)
				return;
			m_start = m_end = ucspt;

			auto matrix = m_ucs->getMatrix();
			show3DRubberLine(true);
			set3DRubberLineP1(m_start * matrix);
			set3DRubberLineP2(m_end * matrix);
			prompt(3, tr("指定第二个点: "));
		}
		return;
	}

	if (status() >= 3)
	{
		osg::Vec3d ucspt;
		if (data.type() == QVariant::Bool && data.toBool())
		{
			selector->clearSelection();
			drawFinish(scene);
			emit finished();
			return;
		}
		else if (rawInput == QString("U") || rawInput == QString("u"))
		{
			if (status() == 3)
			{
				remark(tr("无效的输入"));
				return;
			}
			assert(m_cloneVec.size() >= 2);
			widget3D->pauseRenderThread();
			for (auto clone : m_cloneVec[m_cloneVec.size() - 1])
			{
				auto parent = clone->getParent();
				if (parent)
				{
					parent->removeChild(clone);
				}
			}
			widget3D->resumeRenderThread();

			m_cloneVec.pop_back();
			if (m_cloneVec.size() > 1)
			{
				prompt(status() - 1, tr("指定第二个点或[回退(U)]<结束>: "));
			}
			else
			{
				prompt(status() - 1, tr("指定第二个点: "));
			}
			return;
		}
		else
		{
			if (getPoint2D(*m_ucs, data, rawInput, cs, ucspt))
			{
				//记录下本次偏移量
				auto thisoffset = ucspt - m_end;
				m_end = ucspt;
				auto matrix = m_ucs->getMatrix();
				set3DRubberLineP2(m_end * matrix);

				if (cs == CS_MOUSEMOVE)
				{
					for (auto clone : m_cloneVec[0])
					{
						clone->move(thisoffset);
					}
				}
				else
				{
					m_end = ucspt;
					const osg::Vec3d offset = m_end - m_start;
					set3DRubberLineP2(m_end);
					std::vector<std::shared_ptr<Ent>> copyTemp;
					for (int i = 0; i < m_origins.size(); ++i)
					{
						auto clone = m_origins[i]->clone();
						auto parent = clone->getParent();
						if (parent)
						{
							clone->move(offset);
							widget3D->pauseRenderThread();
							parent->addChild(clone);
							widget3D->resumeRenderThread();
							copyTemp.push_back(clone);
						}
					}
					m_cloneVec.push_back(copyTemp);
					prompt(status() + 1, tr("指定第二个点或[回退(U)]<结束>: "));
				}
			}
			else
			{
				remark(tr("无效的输入"));
				return;
			}
		}
		return;
	}
}

void Copy2DHandler::removeTempObjects()
{
	auto widget3D = getWidget();
	if (m_cloneVec.size() > 0)
	{
		widget3D->pauseRenderThread();
		for (auto clones : m_cloneVec)
		{
			for (auto clone : clones)
			{
				auto parent = clone->getParent();
				if (parent)
				{
					parent->removeChild(clone);
				}
			}
		}
		widget3D->resumeRenderThread();
	}
}

void Copy2DHandler::drawFinish(Scene* scene)
{
	auto widget3D = getWidget();
	std::set<std::shared_ptr<INode>> result;
	widget3D->pauseRenderThread();
	for (int i = 0; i < m_cloneVec.size(); ++i)
	{
		for (auto clone : m_cloneVec[i])
		{
			auto parent = clone->getParent();
			if (parent)
			{
				parent->removeChild(clone);
			}
		}
	}
	widget3D->resumeRenderThread();

	if (m_cloneVec.size() >= 2)
	{
		auto undoStack = scene->undoStack();
		for (int i = 1; i < m_cloneVec.size(); ++i)
		{
			for (auto clone : m_cloneVec[i])
			{
				result.insert(clone);
			}
		}
		undoStack->push(new OpAdd(result));
	}
}
